package com.nolon.flange.model

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.nolon.flange.model.Part

@Entity(tableName = "raw_info_table")
data class RawInfo(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "raw_id") val id: Int = 0,
    @ColumnInfo(name = "raw_project_id") val projectId: Int = 0,
    val length: Int = 5980,
    @ColumnInfo(name = "material_spec") val materialSpec: String = "30",
    @ColumnInfo(name = "actual_material_spec") val actualSpec: Int = 30,
    @ColumnInfo(name = "unit_price") val unitPrice: Float = 0f,
    @ColumnInfo(name = "max_combination") val maxCombination: Int = 5
) {
    @Ignore
    val parts: ArrayList<Part> = arrayListOf()

    @Ignore
    var combination: Int = 0

    fun usageRate(): Float = usedLength().toFloat() / length

    fun tailLength() = length - usedLength()

    fun usedLength(): Int =
        if (parts.isEmpty()) 0 else parts.map { it.quantity }.reduce { acc, f -> acc + f }

    fun ifRoom(part: Part): Boolean {
        val existed = parts.find { it.quantity == part.quantity }
        return if (usedLength() + part.quantity <= length && combination <= maxCombination) {
            parts.add(part)
            parts.sortBy { it.quantity }
            if (existed == null) {
                combination++
            }
            true
        } else false
    }

    fun info(): String {
        val types = parts.map { it.quantity }.toSet().toList()
        var str = ""
        types.forEach { f ->
            str += f.toString() + " × " + parts.count { it.quantity == f } + "\n"
        }
        return str.trimEnd('\n')
    }

    override fun equals(other: Any?): Boolean {
        if (other is RawInfo) {
            if (this.projectId == other.projectId
                && this.length == other.length
                && this.materialSpec == other.materialSpec
                && this.actualSpec == other.actualSpec
                && this.unitPrice == other.unitPrice
                && this.maxCombination == other.maxCombination
            ) {
                return true
            }
        }
        return false
    }
}
